package com.yzion.baselib.imageloader

import android.app.Activity
import android.content.Context
import android.graphics.drawable.Drawable
import android.view.View
import android.widget.ImageView
import androidx.annotation.DrawableRes
import androidx.annotation.IntRange
import com.blankj.utilcode.util.AppUtils
import com.blankj.utilcode.util.ThreadUtils
import com.bumptech.glide.Priority
import com.bumptech.glide.integration.webp.decoder.WebpDrawable
import com.bumptech.glide.integration.webp.decoder.WebpDrawableTransformation
import com.bumptech.glide.load.MultiTransformation
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.resource.bitmap.CircleCrop
import com.bumptech.glide.load.resource.bitmap.FitCenter
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.target.CustomViewTarget
import com.yzion.baselib.app.GlideApp
import com.yzion.baselib.app.GlideOptions
import com.yzion.baselib.app.GlideRequests
import jp.wasabeef.glide.transformations.BlurTransformation


/**
 * ZJJ
 * 统一配置的图片加载工具，支持加载圆形图片，圆角图片，图片高斯模糊等
 * 使用Glide库加载图片
 */
open class ImageLoader {

    fun checkContextOK(context: Context): Boolean {
        return (context is Activity && (context.isDestroyed || context.isFinishing)).not()
    }

    fun getGlideRequests(context: Context): GlideRequests {
        return GlideApp.with(context)
    }

    //-----------加载图片-----------//

    //同步方法
    fun loadSync(
        context: Context,
        model: Any?,
    ): Drawable? {
        if (checkContextOK(context).not()) return null
        return getGlideRequests(context).load(model).apply(requestOptions()).load(model).submit()
            .get()
    }

    /**
     * 加载图片
     */
    fun load(
        model: Any?,
        target: ImageView,
        options: GlideOptions = GlideOptions(),
    ) {
        if (checkContextOK(target.context).not()) return
        ThreadUtils.runOnUiThread {
            getGlideRequests(target.context).load(model).apply(requestOptions(options))
                .transition(DrawableTransitionOptions.withCrossFade()).into(target)
        }
    }

    /**
     * 预加载
     */
    fun preload(context: Context, model: Any?, requestListener: RequestListener<Drawable>? = null) {
        if (checkContextOK(context).not()) {
            return
        }
        getGlideRequests(context).load(model).apply(requestOptions())
            .skipMemoryCache(true).priority(Priority.LOW).addListener(requestListener).preload()
    }

    /**
     * 加载图片+回调
     */
    fun loadCallback(
        context: Context,
        model: Any?,
        customTarget: CustomTarget<Drawable>,
        options: GlideOptions = GlideOptions(),
    ) {
        if (checkContextOK(context).not()) {
            return
        }
        getGlideRequests(context).load(model).apply(requestOptions(options))
            .into(customTarget)
    }

    /**
     * 加载图片+回调
     */
    fun loadCallback(
        model: Any?,
        customViewTarget: CustomViewTarget<out View, Drawable>,
        options: GlideOptions = GlideOptions(),
    ) {
        if (checkContextOK(customViewTarget.view.context).not()) {
            return
        }
        getGlideRequests(customViewTarget.view.context).load(model).apply(requestOptions(options))
            .into(customViewTarget)
    }

    //加载图片+高斯模糊
    fun loadBlur(
        url: Any?,
        target: ImageView,
        @IntRange(from = 0, to = 25) blur: Int,
        options: GlideOptions = GlideOptions(),
    ) {
        if (checkContextOK(target.context).not()) return
        val requestOptions = requestOptions(options).transform(BlurTransformation(blur))
        getGlideRequests(target.context).load(url).apply(requestOptions)
            .transition(DrawableTransitionOptions.withCrossFade()).into(target)
    }


    //-----------加载动画图片-----------//

    /**
     * 加载webp动画图片
     */
    fun loadWebp(model: Any?, target: ImageView) {
        if (checkContextOK(target.context).not()) return
        val fitCenter = FitCenter()
        getGlideRequests(target.context).load(model).apply(requestOptions())
            .optionalTransform(fitCenter)
            .optionalTransform(WebpDrawable::class.java, WebpDrawableTransformation(fitCenter))
            .into(target)
    }

    //-----------加载圆形图片-----------//

    /**
     * 加载圆形图片
     */
    fun loadCircle(url: Any?, target: ImageView, options: GlideOptions = GlideOptions()) {
        if (checkContextOK(target.context).not()) return
        val requestOptions = requestOptions(options).optionalCircleCrop()
        getGlideRequests(target.context).load(url).apply(requestOptions)
            .transition(DrawableTransitionOptions.withCrossFade()).into(target)
    }

    /**
     * 加载圆形图片+回调
     */
    fun loadCircleCallback(
        context: Context,
        url: Any?,
        customViewTarget: CustomViewTarget<View, Drawable>,
        options: GlideOptions = GlideOptions(),
    ) {
        if (checkContextOK(context).not()) {
            return
        }
        val requestOptions = requestOptions(options).optionalCircleCrop()
        getGlideRequests(context).load(url).apply(requestOptions)
            .transition(DrawableTransitionOptions.withCrossFade()).into(customViewTarget)
    }

    /**
     * 加载圆形图片+高斯模糊
     */
    fun loadCircleBlur(
        url: Any?,
        target: ImageView,
        @IntRange(from = 0, to = 25) blur: Int,
        options: GlideOptions = GlideOptions(),
    ) {
        if (checkContextOK(target.context).not()) return
        val multiTransformation = MultiTransformation(CircleCrop(), BlurTransformation(blur))
        val requestOptions = requestOptions(options).transform(multiTransformation)
        getGlideRequests(target.context).load(url).apply(requestOptions)
            .transition(DrawableTransitionOptions.withCrossFade()).into(target)
    }

    //-----------加载圆角图片-----------//

    /**
     *  加载圆角图片
     */
    fun loadCorner(
        url: Any?, target: ImageView, radius: Int, options: GlideOptions = GlideOptions(),
    ) {
        if (checkContextOK(target.context).not()) return
        //设置图片圆角角度
        val requestOptions = requestOptions(options).transform(RoundedCorners(radius))
        getGlideRequests(target.context).load(url).apply(requestOptions)
            .transition(DrawableTransitionOptions.withCrossFade()).into(target)
    }

    /**
     * 加载圆角图片+高斯模糊
     */
    fun loadCornerBlur(
        url: Any?,
        target: ImageView,
        radius: Int,
        @IntRange(from = 0, to = 25) blur: Int,
        options: GlideOptions = GlideOptions(),
    ) {
        if (checkContextOK(target.context).not()) return
        //设置图片圆角角度
        val multiTransformation =
            MultiTransformation(RoundedCorners(radius), BlurTransformation(blur))
        val requestOptions = requestOptions(options).transform(multiTransformation)
        getGlideRequests(target.context).load(url).apply(requestOptions)
            .transition(DrawableTransitionOptions.withCrossFade()).into(target)
    }

    /**
     * 加载圆角图片+回调
     */
    fun loadCornerCallback(
        context: Context,
        url: String?,
        radius: Int,
        customViewTarget: CustomViewTarget<View, Drawable>,
        options: GlideOptions = GlideOptions(),
    ) {
        if (checkContextOK(context).not()) {
            return
        }
        //设置图片圆角角度
        val requestOptions = requestOptions(options).transform(RoundedCorners(radius))
        getGlideRequests(context).load(url).apply(requestOptions)
            .transition(DrawableTransitionOptions.withCrossFade()).into(customViewTarget)
    }

    fun clearMemoryCache(context: Context) {
        ThreadUtils.runOnUiThread {
            GlideApp.get(context).clearMemory()
        }
    }

    fun clearDiskCache(context: Context) {
        GlideApp.get(context).clearDiskCache()
    }

    fun resume(context: Context) {
        getGlideRequests(context).resumeRequests()
    }

    fun pause(context: Context) {
        getGlideRequests(context).pauseRequests()
    }

    fun resOptions(
        @DrawableRes loadingResId: Int = 0,
        @DrawableRes errorResId: Int = 0
    ): GlideOptions {
        return GlideOptions().placeholder(loadingResId).error(errorResId)
    }

    fun requestOptions(options: GlideOptions = GlideOptions()): GlideOptions {
        var request =
            options.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC).timeout(TIME_OUT)
                .priority(Priority.NORMAL)

//        if (options != null) {
//            if (options.loadingResId != Options.RES_NONE) {
//                request = request.placeholder(options.loadingResId)
//            }
//            if (options.errorResId != Options.RES_NONE) {
//                request = request.error(options.errorResId)
//            }
//        }
        return request
    }

//    class Options(
//        @DrawableRes val loadingResId: Int = RES_NONE, @DrawableRes val errorResId: Int = RES_NONE
//    ) {
//
//        companion object {
//            const val RES_NONE = -1
//
//            fun defaultOptions(): Options {
//                return Options(RES_NONE, RES_NONE)
//            }
//        }
//
//    }

    companion object {
        private val imageLoader: ImageLoader by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            ImageLoader()
        }

        @JvmStatic
        fun get(): ImageLoader {
            return imageLoader
        }

        fun Int.toResourcePath(): String {
            return "android.resource://${AppUtils.getAppPackageName()}/$this"
        }

        const val ASSETS_PATH = "file:///android_asset"
        var TIME_OUT = 8 * 1000
    }
}